package be.nepherte.movmanager.client.gui.components;

import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ImageBundle;
import com.google.gwt.user.client.ui.TreeImages;

/**
 * This class represents a tab in the graphical user interface. Each tab has:
 * <ul>
 * 		<li>a name</li>
 * 		<li>a description</li>
 * 		<li>a color</li>
 * </ul>
 * This information is encapsulated in a TabInfo object. The name is used as a visual link label 
 * for the tab. The description serves as a explanation of each tab and will be shown as well.
 * A tab is a single panel of the TabSink. They are meant to be lazily instantiated 
 * (by creating an instance only when necessary) so that the application doesn't
 * pay for all of them on startup.
 * <p>
 * This file is part of MovManager.
 * </p>
 * <p>
 * MovManager is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * </p>
 * <p>
 * MovManager is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * </p>
 * <p>
 * You should have received a copy of the GNU General Public License
 * along with MovManager.  If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses</a>.
 * </p>
 * 
 * @author	Bart Verhoeven, Google Inc.
 * @since	20/05/2009
 * @version	0.1
 */
public abstract class Tab extends Composite {
	
	/**
	 * Constructor for this tab. It has no effect whatsoever.
	 */
	protected Tab() {}

	/**
	 * An image provider to make images available to tabs.
	 */
	public interface Images extends ImageBundle, TreeImages {
		AbstractImagePrototype gwtLogo();
	}

	/**
	 * Encapsulated information about a tab. Holds information about the name, color, description of the tab and the tab itself. 
	 * Each tab is expected to have a static <code>init()</code> method that will be called by the TabSink on startup.
	 */
	public abstract static class TabInfo {
		/**An instance of this tab. */
		private Tab instance;
		/**The name of this tab.*/
		private String name;
		/**The description of this tab.*/
		private String description;
		/**The color of this tab in hexadecimal representation.*/
		private String color;

		/**
		 * Create a TabInfo object. The name is used as a link label on the tab. The description will be shown when the tab is active, 
		 * against a getColor() background.
		 * 
		 * @param	name
		 * 			name of the tab.
		 * @param	desc
		 * 			description of the tab
		 * @param	color
		 * 			the background color of the tab
		 */
		protected TabInfo(String name, String desc, String color) {
			this.name = name;
			this.description = desc;
			this.color = color;
		}

		/**
		 * Create a new instance of this tab.
		 * 
		 * @return	a new tab
		 */
		public abstract Tab createInstance();

		/**
		 * Get the color of this tab.
		 * 
		 * @return	color
		 */
		public String getColor() {
			return color;
		}

		/**
		 * Get the description of this tab.
		 * 
		 * @return	description
		 */
		public String getDescription() {
			return description;
		}

		/**
		 * Get an instance of the tab associated with this TabInfo. If
		 * there already was an instance created, it will return the already
		 * created instance. Else, a new instance is created.
		 * 
		 * @return	an instance of this tab. a new one if none have been created,
		 *         	else an existing one.
		 */
		public final Tab getInstance() {
			if (instance != null)
				return instance;

			return (instance = createInstance());
		}

		/**
		 * Get the name of this tab.
		 * 
		 * @return name
		 */
		public String getName() {
			return name;
		}
	}
	
	/**
	 * Called just before this tab is hidden.
	 */
	public abstract void onHide();

	/**
	 * Called just after this tab is shown.
	 */
	public abstract void onShow();
}
